package com.qdlc.p2p.biz.service.impl;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.annotation.Resource;

import org.springframework.stereotype.Service;

import com.qdlc.p2p.biz.log.score.BaseScoreLog;
import com.qdlc.p2p.biz.log.score.convert.ScoreConvertGoodsApplyLog;
import com.qdlc.p2p.biz.log.score.convert.ScoreConvertGoodsFailLog;
import com.qdlc.p2p.biz.log.score.convert.ScoreConvertGoodsSuccessLog;
import com.qdlc.p2p.biz.service.ScoreConvertService;
import com.qdlc.p2p.biz.util.NoticeTemplateSender;
import com.qdlc.p2p.common.constant.Global;
import com.qdlc.p2p.common.constant.NoticeTplNid;
import com.qdlc.p2p.common.exception.ScoreException;
import com.qdlc.p2p.common.util.DateUtil;
import com.qdlc.p2p.dal.common.model.jpa.OrderFilter.OrderType;
import com.qdlc.p2p.dal.common.model.jpa.PageDataList;
import com.qdlc.p2p.dal.common.model.jpa.QueryParam;
import com.qdlc.p2p.dal.common.model.jpa.SearchFilter;
import com.qdlc.p2p.dal.common.model.jpa.SearchFilter.Operators;
import com.qdlc.p2p.dal.dao.GoodsDao;
import com.qdlc.p2p.dal.dao.ReceivingInfoDao;
import com.qdlc.p2p.dal.dao.ScoreConvertDao;
import com.qdlc.p2p.dal.dao.ScoreDao;
import com.qdlc.p2p.dal.dao.VerifyLogDao;
import com.qdlc.p2p.dal.dto.Goods;
import com.qdlc.p2p.dal.dto.ReceivingInfo;
import com.qdlc.p2p.dal.dto.Score;
import com.qdlc.p2p.dal.dto.ScoreConvert;
import com.qdlc.p2p.dal.dto.VerifyLog;
import com.qdlc.p2p.dal.model.ScoreConvertModel;

@Service("scoreConvertService")
public class ScoreConvertServiceImpl implements ScoreConvertService {

    @Resource
    private ScoreConvertDao scoreConvertDao;

    @Resource
    private GoodsDao goodsDao;

    @Resource
    private ReceivingInfoDao receivingInfoDao;

    @Resource
    private ScoreDao scoreDao;

    @Resource
    private VerifyLogDao verifyLogDao;

    @Override
    public PageDataList<ScoreConvertModel> findPageList(ScoreConvertModel model) {
        return scoreConvertDao.findPageList(model);
    }

    @Override
    public List<ScoreConvertModel> list(int limit) {
        QueryParam param = QueryParam.getInstance();
        param.addOrFilter(new SearchFilter("status", Operators.EQ,
                ScoreConvertModel.IS_DELIVERY), new SearchFilter("status",
                Operators.EQ, ScoreConvertModel.IS_RECEIVE), new SearchFilter(
                "status", Operators.EQ, ScoreConvertModel.PASS_AUDIT));

        param.addOrder(OrderType.DESC, "verifyTime");
        List<ScoreConvert> itemList = scoreConvertDao.findByCriteria(param, 0, limit);
        List<ScoreConvertModel> modelList = new ArrayList<ScoreConvertModel>();
        if (itemList != null && itemList.size() > 0) {
            for (int i = 0; i < itemList.size(); i++) {
                ScoreConvert item = itemList.get(i);
                ScoreConvertModel model_ = new ScoreConvertModel();
                Goods goods = item.getGoods();
                model_.setName(goods.getName());
                model_.setUserName(item.getUser().getHideUserName());
                modelList.add(model_);
            }
        }
        return modelList;
    }

    @Override
    public ScoreConvert getScoreConvertById(long id) {
        return scoreConvertDao.find(id);
    }

    @Override
    public Boolean doConvert(ScoreConvertModel model) {
        if (model == null) {
            return false;
        }
        // 兑换校验
        Goods goods = goodsDao.find(model.getGoodsId());//首先获取商品信息
        Score score = scoreDao.findObjByProperty("user.userId", model.getUserId());//获取积分信息
        model.setScore(goods.getScore());
        model.checkGoods(goods);//判断库存是否足够等
        model.checkScore(score.getValidScore());//判断积分是否足够
        // 保存兑换记录
        ReceivingInfo receivingInfo = receivingInfoDao.find(model.getAddressId());//获取选中的地址信息
        ScoreConvert item = model.prototype();
        double money = goods.getCost() * item.getConvertNum();
        item.setMoney(money);//得到兑换金额
        item.setAddTime(DateUtil.getNow());//兑换时间
        item.setGoods(new Goods(model.getGoodsId()));//商品信息
        item.setReceiveAddress(receivingInfo.getProvince() + receivingInfo.getCity() + receivingInfo.getArea() + receivingInfo.getAddress());//地址
        item.setReceivePhone(receivingInfo.getPhone());//电话
        item.setReceiveMobile(receivingInfo.getMobile());//手机
        item.setReceiver(receivingInfo.getName());//收件人
        item.setStatus(ScoreConvertModel.WAIT_AUDIT);//设置默认等待审核  此处如果需要审核，那么要冻结积分的。
        item = scoreConvertDao.save(item);

        // 会员积分记录信息 更新积分， 更新日志信息
        int value = goods.getScore() * item.getConvertNum();//单个积分*数量
        Global.setTransfer("score", value);
        Global.setTransfer("goodsName", goods.getName());
        Global.setTransfer("convertNum", item.getConvertNum());
        BaseScoreLog bLog = new ScoreConvertGoodsApplyLog(model.getUserId(), value);
        bLog.doEvent();
        // 更新商品的库存信息
        Boolean result = goodsDao.updateStore(model.getGoodsId(), 0, model.getConvertNum(), 0);
        if (item.getId() <= 0 || !result) {
            throw new ScoreException("积分兑换失败！", 1);
        }
        return true;
    }

    @Override
    public Boolean verifyScoreConvert(ScoreConvertModel model) {
        if (model == null || model.getId() <= 0) {
            return false;
        }
        if (model.getStatus() == ScoreConvertModel.NOT_PASS_AUDIT
                || model.getStatus() == ScoreConvertModel.PASS_AUDIT) {
            ScoreConvert item = scoreConvertDao.find(model.getId());
            if (item.getGoods() == null || item.getUser() == null) {
                return false;
            }
            if (item.getStatus() != ScoreConvertModel.WAIT_AUDIT) {
                return false;
            }
            item.setVerifyRemark(model.getVerifyRemark());
            item.setVerifyTime(new Date());
            item.setVerifyOperator(model.getVerifyOperator());
            item.setStatus(model.getStatus());
            int value = item.getScore() * item.getConvertNum();//单个积分*数量
            Global.setTransfer("score", value);
            Global.setTransfer("goodsName", item.getGoods().getName());
            Global.setTransfer("convertNum", item.getConvertNum());
            if (model.getStatus() == ScoreConvertModel.NOT_PASS_AUDIT) {
                BaseScoreLog bLog = new ScoreConvertGoodsFailLog(item.getUser()
                        .getUserId(), value);
                bLog.doEvent();
                Global.setTransfer("scoreConvert", item);
                Global.setTransfer("user", item.getUser());
                Global.setTransfer("verifyRemark", model.getVerifyRemark());
                NoticeTemplateSender.newInstance(item.getUser(), NoticeTplNid.SCORE_CONVERT_FAIL).send();
                Boolean result = goodsDao.updateStore(item.getGoods().getId(),
                        0, -item.getConvertNum(), 0);
                if (!result) {
                    throw new ScoreException("积分兑换商品审核失败！");
                }
            } else if (model.getStatus() == ScoreConvertModel.PASS_AUDIT) {
                BaseScoreLog bLog = new ScoreConvertGoodsSuccessLog(item.getUser().getUserId(), value);
                bLog.doEvent();
                Boolean result = goodsDao.updateStore(item.getGoods().getId(),
                        0, -item.getConvertNum(), item.getConvertNum());
                if (!result) {
                    throw new ScoreException("积分兑换商品审核失败！");
                }
            }
            scoreConvertDao.update(item);
            VerifyLog log = new VerifyLog(model.getVerifyOperator(),
                    "scoreConvert", model.getId(), 1, model.getStatus(), model.getVerifyRemark());
            verifyLogDao.save(log);
            return true;
        }
        return false;
    }

    @Override
    public void update(ScoreConvert item) {
        scoreConvertDao.update(item);
        Global.setTransfer("scoreConvert", item);
        Global.setTransfer("user", item.getUser());
        NoticeTemplateSender.newInstance(item.getUser(), NoticeTplNid.SCORE_DELIVERY_SUCC);
    }

    @Override
    public void delete(long id) {
        ScoreConvert scoreConvert = getScoreConvertById(id);
        update(scoreConvert);
    }
}
